package com.ruoyi.mp.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.db.domain.system.*;
import com.ruoyi.db.domain.web.MpClientAddress;
import com.ruoyi.db.domain.web.MpIncomeRecord;
import com.ruoyi.db.mapper.system.*;
import com.ruoyi.db.mapper.web.MpClientAddressMapper;
import com.ruoyi.db.mapper.web.MpIncomeRecordMapper;
import com.ruoyi.mp.service.IMpClientCartService;
import com.ruoyi.mp.service.IMpClientOrderService;
import com.ruoyi.mp.utils.KDNiaoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 【商城用户】Service业务层处理
 * 
 * @author ruoyi
 * @date 2022-07-23
 */
@Service
@Transactional(rollbackOn = Exception.class)
public class MpClientOrderServiceImpl implements IMpClientOrderService
{
    @Autowired
    private MpClientOrderMapper mpClientOrderMapper;
    @Autowired
    private PcProductMapper pcProductMapper;
    @Autowired
    private MpIncomeRecordMapper mpIncomeRecordMapper;
    @Autowired
    private MpClientMapper mpClientMapper;
    @Autowired
    private MpClientSubOrderMapper mpClientSubOrderMapper;
    @Autowired
    private PcProComboMapper pcProComboMapper;
    @Autowired
    private PcExpressDeliveryMapper pcExpressDeliveryMapper;
    @Autowired
    private MpClientAddressMapper mpClientAddressMapper;
    @Autowired
    private IMpClientCartService mpClientCartService;
    @Autowired
    private RedisService redisService;

    /**
     * 查询【商城用户】列表
     * 
     * @param mpClientOrder 【商城用户】
     * @return 【商城用户】
     */
    @Override
    public List<MpClientOrder> selectMpClientOrderListByStatus(MpClientOrder mpClientOrder)
    {
        List<MpClientOrder> list =  mpClientOrderMapper.selectMpClientOrderListByStatus(mpClientOrder);
        for (MpClientOrder order: list) {
            MpClientSubOrder subOrder = new MpClientSubOrder();
            subOrder.setOrderId(order.getOrderId());
            List<MpClientSubOrder> subs = mpClientSubOrderMapper.selectMpClientSubOrderList(subOrder);
            for (MpClientSubOrder subOrder1: subs) {
                if(subOrder1.getProId()!=null){
                    PcProduct pcProduct = pcProductMapper.selectPcProductByProId(subOrder1.getProId());
                    subOrder1.setProName(pcProduct.getProName());
                    subOrder1.setSellType(pcProduct.getSellType().intValue());
                    subOrder1.setMasterImg(pcProduct.getMasterImg());
                    subOrder1.setRmbPrice(pcProduct.getRmbPrice());
                    subOrder1.setGoldBeanPrice(pcProduct.getGoldBeanPrice());
                    subOrder1.setSilverBeanPrice(pcProduct.getSilverBeanPrice());
                    if(pcProduct.getReturnRate()!=null){
                        subOrder1.setReturnGold((new BigDecimal(pcProduct.getReturnRate().toString())).multiply(new BigDecimal(subOrder1.getProCount().toString())).setScale( 2, BigDecimal.ROUND_HALF_UP ));
                    }else{
                        subOrder1.setReturnGold(new BigDecimal(0));
                    }
                }else if(subOrder1.getProComboId()!=null){
                    PcProCombo pcProCombo = pcProComboMapper.selectPcProComboByProComboId(subOrder1.getProComboId());
                    subOrder1.setProName(pcProCombo.getProComboName());
                    subOrder1.setSellType(1);
                    subOrder1.setMasterImg(pcProCombo.getMasterImg());
                    subOrder1.setRmbPrice(pcProCombo.getRmbPrice());
                    if(pcProCombo.getReturnRate()!=null){
                        subOrder1.setReturnGold((new BigDecimal(pcProCombo.getReturnRate().toString())).multiply(new BigDecimal(subOrder1.getProCount().toString())).setScale( 2, BigDecimal.ROUND_HALF_UP ));
                    }else{
                        subOrder1.setReturnGold(new BigDecimal(0));
                    }
                }
            }
            order.setSubOrders(subs);

        }
        return list;
    }

    @Override
    public MpClientOrder selectMpClientOrderByOrderId(String orderId) {
        MpClientOrder order = mpClientOrderMapper.selectMpClientOrderByOrderId(orderId);
        MpClientAddress address  = mpClientAddressMapper.selectMpClientAddressByAddressId(order.getAddressId());
        if(address!=null){
            order.setClientName(address.getContactName());
            order.setClientMobile(address.getContactPhone());
            order.setProvince(address.getProvinceName());
            order.setCity(address.getCityName());
            order.setCounty(address.getCountyName());
            order.setAddress(address.getAddress());
        }
        MpClientSubOrder subOrder = new MpClientSubOrder();
        subOrder.setOrderId(orderId);
        List<MpClientSubOrder> subs = mpClientSubOrderMapper.selectMpClientSubOrderList(subOrder);
        for (MpClientSubOrder subOrder1: subs) {
            if(subOrder1.getProId()!=null){
                PcProduct pcProduct = pcProductMapper.selectPcProductByProId(subOrder1.getProId());
                subOrder1.setProName(pcProduct.getProName());
                subOrder1.setSellType(pcProduct.getSellType().intValue());
                subOrder1.setMasterImg(pcProduct.getMasterImg());
                subOrder1.setRmbPrice(pcProduct.getRmbPrice());
                subOrder1.setGoldBeanPrice(pcProduct.getGoldBeanPrice());
                subOrder1.setSilverBeanPrice(pcProduct.getSilverBeanPrice());
                BigDecimal rmbPrice = pcProduct.getRmbPrice()==null?new BigDecimal(0):pcProduct.getRmbPrice();
                if(pcProduct.getReturnRate()!=null){
                    subOrder1.setReturnGold((new BigDecimal(pcProduct.getReturnRate().toString())).multiply(new BigDecimal(subOrder1.getProCount().toString())).setScale( 2, BigDecimal.ROUND_HALF_UP ));
                }else{
                    subOrder1.setReturnGold(new BigDecimal(0));
                }
            }else if(subOrder1.getProComboId()!=null){
                PcProCombo pcProCombo = pcProComboMapper.selectPcProComboByProComboId(subOrder1.getProComboId());
                subOrder1.setProName(pcProCombo.getProComboName());
                subOrder1.setSellType(1);
                subOrder1.setMasterImg(pcProCombo.getMasterImg());
                subOrder1.setRmbPrice(pcProCombo.getRmbPrice());
                BigDecimal rmbPrice = pcProCombo.getRmbPrice()==null?new BigDecimal(0):pcProCombo.getRmbPrice();
                if(pcProCombo.getReturnRate()!=null){
                    subOrder1.setReturnGold((new BigDecimal(pcProCombo.getReturnRate().toString())).multiply(new BigDecimal(subOrder1.getProCount().toString())).setScale( 2, BigDecimal.ROUND_HALF_UP ));
                }else{
                    subOrder1.setReturnGold(new BigDecimal(0));
                }
            }
        }
        order.setSubOrders(subs);
        return order;
    }
    /**
     * 新增【用户订单】
     *
     * @param mpClientOrder 【商城用户】
     * @return 结果
     */
    @Override
    public void insertMpClientOrder(MpClientOrder mpClientOrder, MpClient client)
    {
        mpClientOrder.setPayTime(new Date());
        mpClientOrder.setOrderStatus(201l);
        MpClientSubOrder subOrder = new MpClientSubOrder();
        subOrder.setOrderId(mpClientOrder.getOrderId());
        List<MpClientSubOrder> subOrders = mpClientSubOrderMapper.selectMpClientSubOrderList(subOrder);
        if(mpClientOrder.getSellType()==1){
                BigDecimal goldPay = mpClientOrder.getGoldBeanPay();
                if(goldPay!=null&&goldPay.compareTo(new BigDecimal(0))>0){
                    if(client.getGoldBeanBalance().compareTo(goldPay)<0){
                        throw new ServiceException("金藻余额不足");
                    }
                    BigDecimal goldSum = client.getGoldBeanBalance().subtract(goldPay);
                     for (MpClientSubOrder subOrder1:subOrders){
                         if(subOrder1.getProId()!=null){
                             PcProduct pcProduct = pcProductMapper.selectPcProductByProId(subOrder1.getProId());
                             BigDecimal rmbPrice = pcProduct.getRmbPrice()==null?new BigDecimal(0):pcProduct.getRmbPrice();
                             if(pcProduct.getReturnRate()!=null){
                                 subOrder1.setReturnGold((new BigDecimal(pcProduct.getReturnRate().toString())).multiply(new BigDecimal(subOrder1.getProCount().toString())).setScale( 2, BigDecimal.ROUND_HALF_UP ));
                             }else{
                                 subOrder1.setReturnGold(new BigDecimal(0));
                             }
                         }else if(subOrder1.getProComboId()!=null){
                             PcProCombo pcProCombo = pcProComboMapper.selectPcProComboByProComboId(subOrder1.getProComboId());
                             BigDecimal rmbPrice = pcProCombo.getRmbPrice()==null?new BigDecimal(0):pcProCombo.getRmbPrice();
                             if(pcProCombo.getReturnRate()!=null){
                                 subOrder1.setReturnGold((new BigDecimal(pcProCombo.getReturnRate().toString())).multiply(new BigDecimal(subOrder1.getProCount().toString())).setScale( 2, BigDecimal.ROUND_HALF_UP ));
                             }else{
                                 subOrder1.setReturnGold(new BigDecimal(0));
                             }
                         }
                     }

                    BigDecimal returnGold = subOrders.stream().map( MpClientSubOrder:: getReturnGold).reduce(BigDecimal.ZERO, BigDecimal::add); //BigDecimal类型

                    MpClient updClient = new MpClient();
                    updClient.setClientId(client.getClientId());
                    updClient.setGoldBeanBalance(goldSum.add(returnGold));
                    if(mpClientMapper.updateMpClient(updClient)>0){
                        MpIncomeRecord record = new MpIncomeRecord();
                        record.setClientId(client.getClientId());
                        record.setCreateTime(new Date());
                        record.setIsIncome(0l);
                        record.setAmount(mpClientOrder.getOrderAmount());
                        record.setContent("购买商品");
                        record.setType(1l);
                        record.setCurrentBalance(updClient.getGoldBeanBalance().subtract(returnGold));
                        mpIncomeRecordMapper.insertMpIncomeRecord(record);

                        if(returnGold.compareTo(new BigDecimal("0"))!=0){
                            MpIncomeRecord recordReturn = new MpIncomeRecord();
                            recordReturn.setClientId(client.getClientId());
                            recordReturn.setCreateTime(new Date());
                            recordReturn.setIsIncome(1l);
                            recordReturn.setAmount(returnGold);
                            recordReturn.setContent("购买商品奖励");
                            recordReturn.setType(1l);
                            recordReturn.setCurrentBalance(updClient.getGoldBeanBalance());
                            mpIncomeRecordMapper.insertMpIncomeRecord(recordReturn);
                        }
                    }else{
                        throw new ServiceException("服务异常");
                    }
                }else{
                    throw new ServiceException("订单金额参数异常");
                }
                mpClientOrderMapper.updateMpClientOrder(mpClientOrder);
        }
        if(mpClientOrder.getSellType()==2){
                BigDecimal goldPay = mpClientOrder.getGoldBeanPay();
                if(goldPay!=null&&goldPay.compareTo(new BigDecimal(0))>0){
                    if(client.getGoldBeanBalance().compareTo(goldPay)<0){
                        throw new ServiceException("金藻余额不足");
                    }
                    if(client.getSilverBeanBalance().compareTo(mpClientOrder.getSilverBeanPay())<0){
                        throw new ServiceException("银藻余额不足");
                    }
                    BigDecimal goldSum = client.getGoldBeanBalance().subtract(goldPay);
                    BigDecimal silverSum = client.getSilverBeanBalance().subtract(mpClientOrder.getSilverBeanPay());

                    MpClient updClient = new MpClient();
                    updClient.setClientId(client.getClientId());
                    updClient.setGoldBeanBalance(goldSum);
                    updClient.setSilverBeanBalance(silverSum);
                    if(mpClientMapper.updateMpClient(updClient)>0){
                        MpIncomeRecord record = new MpIncomeRecord();
                        record.setClientId(client.getClientId());
                        record.setCreateTime(new Date());
                        record.setIsIncome(0l);
                        record.setAmount(mpClientOrder.getSilverBeanPay());
                        record.setContent("购买商品");
                        record.setType(2l);
                        record.setCurrentBalance(updClient.getSilverBeanBalance());
                        mpIncomeRecordMapper.insertMpIncomeRecord(record);
                        MpIncomeRecord record1 = new MpIncomeRecord();
                        record1.setClientId(client.getClientId());
                        record1.setCreateTime(new Date());
                        record1.setIsIncome(0l);
                        record1.setAmount(goldPay);
                        record1.setContent("购买商品");
                        record1.setType(1l);
                        record1.setCurrentBalance(updClient.getGoldBeanBalance());
                        mpIncomeRecordMapper.insertMpIncomeRecord(record1);
                    }else{
                        throw new ServiceException("服务异常");
                    }
                }else{
                    throw new ServiceException("订单金额参数异常");
                }
            mpClientOrderMapper.updateMpClientOrder(mpClientOrder);
        }

        for (MpClientSubOrder sub:subOrders) {
            if(sub.getProId()!=null&&sub.getProId()!=0){
                PcProduct pcProduct = pcProductMapper.selectPcProductByProId(sub.getProId());
                pcProduct.setStorageAmount(pcProduct.getStorageAmount()-sub.getProCount());
                pcProduct.setSellAmount(pcProduct.getSellAmount()==null?0:pcProduct.getSellAmount()+sub.getProCount());
                pcProductMapper.updatePcProduct(pcProduct);
            }
            if(sub.getProComboId()!=null&&sub.getProComboId()!=0){
                PcProCombo combo = pcProComboMapper.selectPcProComboByProComboId(sub.getProComboId());
                combo.setStorageAmount(combo.getStorageAmount()-sub.getProCount());
                combo.setSellAmount(combo.getSellAmount()==null?0:combo.getSellAmount()+sub.getProCount());
                pcProComboMapper.updatePcProCombo(combo);
            }
        }
        //去掉用户购物车付款商品
        if(mpClientOrder.getSubCartIds()!=null&&mpClientOrder.getSubCartIds().length!=0){
            mpClientCartService.deleteMpClientCartByCartIds(mpClientOrder.getSubCartIds(),client.getClientId());
        }
    }

    @Override
    public MpClientOrder insertMpClientOrderWaitPay(MpClientOrder mpClientOrder) {
        String prefix = DateUtil.format(new Date(), "yyyyMMdd");
        String maxOrderId = mpClientOrderMapper.getMaxOrderId(prefix);
        long times = 1L;
        if (null != maxOrderId) {
            String stuffix = maxOrderId.toString().substring(8);
            times = Long.parseLong(stuffix) + 1L;
        }
        String orderId = prefix.toString() + NumberUtil.decimalFormat("0000", times);
        mpClientOrder.setOrderId(orderId);
        if(mpClientOrderMapper.insertMpClientOrder(mpClientOrder)>0){
            //插入子订单
            List<MpClientSubOrder> childs = mpClientOrder.getSubOrders();
            int i = 0;
            Date now = new Date();
            for (MpClientSubOrder subOrder:childs) {
                subOrder.setOrderId(orderId);
                subOrder.setSubOrderId(orderId+ "-" + (i + 1));
                subOrder.setCreateTime(now);
                mpClientSubOrderMapper.insertMpClientSubOrder(subOrder);
                i++;
            }
            redisService.setCacheObject(orderId,"ORDER_DELETE",2l, TimeUnit.HOURS);
        }
        //去掉用户购物车付款商品
        if(mpClientOrder.getSubCartIds()!=null&&mpClientOrder.getSubCartIds().length!=0){
            mpClientCartService.deleteMpClientCartByCartIds(mpClientOrder.getSubCartIds(),mpClientOrder.getClientId());
        }
        return mpClientOrder;
    }

    /**
     * 修改【用户订单】
     *
     * @param mpClientOrder 【商城用户】
     * @return 结果
     */
    @Override
    public int updateMpClientOrder(MpClientOrder mpClientOrder)
    {
        return mpClientOrderMapper.updateMpClientOrder(mpClientOrder);
    }

    @Override
    public String getOrderLogistInfo(String orderId) {
        MpClientOrder order = mpClientOrderMapper.selectMpClientOrderByOrderId(orderId);
        PcExpressDelivery delivery = pcExpressDeliveryMapper.selectPcExpressDeliveryById(order.getExpressId());
        try {
            String res = KDNiaoUtils.orderOnlineByJson(delivery.getExpCode(),order.getLogisticsNumber(),"");
            return res;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteByOrderId(String orderId) {
        if(mpClientOrderMapper.deleteMpClientOrderByOrderId(orderId)>0){
            mpClientSubOrderMapper.deleteMpClientSubOrderByOrderId(orderId);
        }
    }

    @Override
    public void insertWxClientOrder(MpClientOrder mpClientOrder) {
        mpClientOrder.setPayTime(new Date());
        mpClientOrder.setOrderStatus(201l);
        mpClientOrder.setPayType("1");
        mpClientOrder.setSellType(1);
        MpClientSubOrder subOrder = new MpClientSubOrder();
        subOrder.setOrderId(mpClientOrder.getOrderId());
        MpClient client = mpClientMapper.selectMpClientByClientId(mpClientOrder.getClientId());
        List<MpClientSubOrder> subOrders = mpClientSubOrderMapper.selectMpClientSubOrderList(subOrder);
            BigDecimal rmbPay = mpClientOrder.getRmbPay();
            BigDecimal goldSum = client.getGoldBeanBalance();
            if(rmbPay!=null&&rmbPay.compareTo(new BigDecimal(0))>0){
                for (MpClientSubOrder subOrder1:subOrders){
                    if(subOrder1.getProId()!=null){
                        PcProduct pcProduct = pcProductMapper.selectPcProductByProId(subOrder1.getProId());
                        if(pcProduct.getReturnRate()!=null){
                            subOrder1.setReturnGold((new BigDecimal(pcProduct.getReturnRate().toString())).multiply(new BigDecimal(subOrder1.getProCount().toString())).setScale( 2, BigDecimal.ROUND_HALF_UP ));
                        }else{
                            subOrder1.setReturnGold(new BigDecimal(0));
                        }
                    }else if(subOrder1.getProComboId()!=null){
                        PcProCombo pcProCombo = pcProComboMapper.selectPcProComboByProComboId(subOrder1.getProComboId());
                        if(pcProCombo.getReturnRate()!=null){
                            subOrder1.setReturnGold((new BigDecimal(pcProCombo.getReturnRate().toString())).multiply(new BigDecimal(subOrder1.getProCount().toString())).setScale( 2, BigDecimal.ROUND_HALF_UP ));
                        }else{
                            subOrder1.setReturnGold(new BigDecimal(0));
                        }
                    }
                }
                BigDecimal returnGold = subOrders.stream().map( MpClientSubOrder:: getReturnGold).reduce(BigDecimal.ZERO, BigDecimal::add); //BigDecimal类型
                MpClient updClient = new MpClient();
                updClient.setClientId(client.getClientId());
                updClient.setGoldBeanBalance(goldSum.add(returnGold));
                if(mpClientMapper.updateMpClient(updClient)>0){
                    MpIncomeRecord record = new MpIncomeRecord();
                    record.setClientId(client.getClientId());
                    record.setCreateTime(new Date());
                    record.setIsIncome(0l);
                    record.setAmount(mpClientOrder.getRmbPay());
                    record.setContent("购买商品");
                    record.setType(3l);
                    record.setCurrentBalance(goldSum);
                    mpIncomeRecordMapper.insertMpIncomeRecord(record);

                    if(returnGold.compareTo(new BigDecimal("0"))!=0){
                        MpIncomeRecord recordReturn = new MpIncomeRecord();
                        recordReturn.setClientId(client.getClientId());
                        recordReturn.setCreateTime(new Date());
                        recordReturn.setIsIncome(1l);
                        recordReturn.setAmount(returnGold);
                        recordReturn.setContent("购买商品奖励");
                        recordReturn.setType(1l);
                        recordReturn.setCurrentBalance(updClient.getGoldBeanBalance());
                        mpIncomeRecordMapper.insertMpIncomeRecord(recordReturn);
                    }
                }else{
                    throw new ServiceException("服务异常");
                }
            }else{
                throw new ServiceException("订单金额参数异常");
            }
            mpClientOrderMapper.updateMpClientOrder(mpClientOrder);
    }

    @Override
    public MpClientOrder selectByOrderId(String orderId) {
        return mpClientOrderMapper.selectMpClientOrderByOrderId(orderId);
    }


}
